package com.example.atomics;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;

@Slf4j
class Example {
    public volatile Boolean isInit = Boolean.FALSE;
    static final AtomicReferenceFieldUpdater<Example, Boolean> FieldUpdater = AtomicReferenceFieldUpdater.newUpdater(Example.class, Boolean.class, "isInit");

    // 避免使用Synchronize
    public void init(Example example) {
        if (FieldUpdater.compareAndSet(example, Boolean.FALSE, Boolean.TRUE)) {
            log.info("---start init");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                log.info("Exception", e.fillInStackTrace());
            }
            log.info("---end init");
        } else {
            log.info("---抢夺失败，已经有线程在修改中");
        }
    }

}


/**
 * 多线程并发调用一个类的初始化方法，如果未被初始化过，将执行初始化工作，要求只能初始化一次
 */
public class AtomicReferenceFieldUpdaterDemo {
    public static void main(String[] args) {
        Example example = new Example();
        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                example.init(example);
            }, "thread-" + i).start();
        }
    }
}
